/**
 * 给定一个数组A，一个正整数M，问数组A中有多少个不同的子序列其LCM是M。
 * 首先将M做一个分解： M = p1 ^ k1 * p2 ^ k2 * ... pn ^ kn
 * M在1E16,因此n最多为13，分解的复杂度在O(sqrt(M))
 * 
 * 对每一个Ai，构造一个n位的二进制数：
 *     如果Ai不是M的因子则忽略
 *     如果Ai恰好含有kj个pj，则将第j位设置为1
 * 注意到如此构造出来的不同的二进制数最多有2^13-1个，而数组长度是1E5，因此中间必然有重复。
 * 因此首先要对A做一个计数，最后得到一个二进制数的多重集合，记作C。C的长度最多在2^13-1。
 * 
 * 于是原问题转化为了在C数组中选若干个数，令位或的结果为全1，问方案总数
 * 令Dij是到C数组的第i个元素，位或结果为j的方案总数，使用刷表法：
 * D[i+1][j | C[i+1]] = D[i][j | C[i + 1]] + D[i][j] * 2 ^ (Cnt[i + 1] - 1)
 * 其中 C[i+1] 表示数组C的第i+1个元素， Cnt[i+1]表示该元素的数量。
 * 
 * D初始化时全为零即可。D最大可能是2^26方，因此可以使用滚动优化，使用2 * 2 ^13即可。
 * 复杂度为 O(sqrt(M) + NK + 4 ^ K)， 其中K最大为13。
 * 
 * DP方程中需要计算2的幂，如果每一次都用快速幂，有两个点超时
 * 可以实现计算出所有的2的幂，取数组元素即可。
 * 
 * 分解M可以使用PollardRho方法，不过改用了PollardRho方法，时间基本不变， 683ms -> 680ms。
 * 
 * 求方案总数还可以使用容斥，朴素的容斥如果不改变枚举对象，是K * 4^K，超时。使用计数器以后似乎是3^K
 * 高级的容斥等价于SOSDP，或者FWT变换，或者Zeta-Mobius变换。
 * 可以将4^k优化为K * 2^K。
 */
#include <bits/stdc++.h>
#include <bits/extc++.h>
using namespace std;

using llt = long long;
llt const MOD = 998244353LL;
vector<llt> POW;

int N;
llt M;
vector<llt> A;
vector<pair<llt, int>> B;
vector<pair<unsigned, int>> C;
array<vector<llt>, 2> D;
map<llt, int> Cnt;

void chkadd(llt & a, llt b){
    if(-1 == b) return;
    if(-1 == a) return (void)(a = b);
    a = (a + b) % MOD;
}

llt proc(){
    POW.reserve(N + 1);
    POW.emplace_back(1LL);
    for(int i=1;i<=N;++i) POW.emplace_back(POW.back() * 2LL % MOD);

    if(1 == M){
        int c = 0;
        for(auto i : A)if(i == 1) c += 1;
        llt ans = POW[c];
        ans = (ans + MOD - 1) % MOD;
        return ans;
    }

    for(auto i : A) Cnt[i] += 1;

    llt m = M;
    for(llt i=2;i*i<=m;++i){
        if(0 == m % i){
            int k = 0;
            while(0 == m % i){
                m /= i, k += 1;
            }
            B.emplace_back(i, k);
        }
    }
    if(m != 1) B.emplace_back(m, 1);
   
    int n = B.size();
    for(const auto & p : Cnt){
        auto t = p.first;
        if(M % t) continue;
        
        unsigned bit = 0;
        for(int i=0;i<n;++i){
            const auto & pp = B[i];
            auto factor = pp.first;
            if(t % factor == 0){
                int k = 0;
                while(0 == t % factor) t /= factor, k += 1;
                if(k == pp.second){
                    bit |= 1 << i;
                }
            }
        }
        C.emplace_back(bit, p.second);
    }    

    int total = 1 << n;
    D[0].assign(total, 0);
    D[1].assign(total, 0);
    D[0][0] = 1;
    int curk = 0, nxtk = 1;

    for(const auto & p : C){
        auto bit = p.first;
        auto cnt = p.second;

        const auto & curd = D[curk];
        auto & nxtd = D[nxtk];
        copy(curd.begin(), curd.end(), nxtd.begin());

        for(int j=0;j<total;++j){
            if(-1 != curd[j]){
                nxtd[j | bit] = (nxtd[j | bit] + curd[j] * (POW[cnt] - 1) % MOD) % MOD;
            }            
        }

        curk ^= 1;
        nxtk ^= 1;
    }

    auto ans = D[curk][(1 << n) - 1];
    return ans;
}

void work(){    
    cin >> N >> M;
    A.assign(N, {});
    for(auto & i : A) cin >> i;
    cout << proc() << endl;
    return;
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int nofkase = 1;
    // cin >> nofkase;
    while(nofkase--) work();
    return 0;
}